package com.example.demo.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.convert.ProductConvert;
import com.example.demo.dao.ProductManagementMapper;
import com.example.demo.dao.ProductMapper;
import com.example.demo.dao.ProductSkuMapper;
import com.example.demo.dao.ProductStatusMapper;
import com.example.demo.domain.app.dto.ProductSpecSkuDTO;
import com.example.demo.domain.app.param.ProductParam;
import com.example.demo.domain.app.vo.ProductDetailVO;
import com.example.demo.domain.app.vo.ProductInfoVO;
import com.example.demo.domain.app.vo.ProductSpecItemVO;
import com.example.demo.domain.app.vo.ProductSpecVO;
import com.example.demo.domain.app.vo.ProductVO;
import com.example.demo.domain.base.PageResult;
import com.example.demo.domain.entity.ProductDO;
import com.example.demo.domain.entity.ProductManagementDO;
import com.example.demo.domain.entity.ProductSkuDO;
import com.example.demo.domain.entity.ProductStatusDO;
import com.example.demo.domain.param.ProductManagementParam;
import com.example.demo.domain.param.ProductManagementQueryParam;
import com.example.demo.domain.param.ProductManagementUpdateParam;
import com.example.demo.domain.vo.ProductManagementDetailVO;
import com.example.demo.domain.vo.ProductManagementVO;
import com.example.demo.service.ProductCategoryService;
import com.example.demo.service.ProductManagementService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * ProductManagementServiceImpl
 *
 * @author haochen78
 * @date 2025/10/30 20:56
 **/
@Service
public class ProductManagementServiceImpl implements ProductManagementService {

    @Autowired
    private ProductManagementMapper productManagementMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ProductStatusMapper productStatusMapper;
    @Autowired
    private ProductSkuMapper productSkuMapper;
    @Autowired
    private ProductCategoryService productCategoryService;


    @Override
    public PageResult<ProductManagementVO> list(ProductManagementQueryParam param) {
        LambdaQueryWrapper<ProductManagementDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(param.getProductType()), ProductManagementDO::getProductType, param.getProductType());
        wrapper.eq(StringUtils.isNotBlank(param.getProductBarcode()), ProductManagementDO::getProductBarcode, param.getProductBarcode());
        wrapper.eq(StringUtils.isNotBlank(param.getProductName()), ProductManagementDO::getProductName, param.getProductName());
        wrapper.eq(StringUtils.isNotBlank(param.getAlias()), ProductManagementDO::getAlias, param.getAlias());
        wrapper.eq(StringUtils.isNotBlank(param.getTagKeywords()), ProductManagementDO::getTagKeywords, param.getTagKeywords());
        wrapper.eq(Objects.nonNull(param.getIsRecommended()), ProductManagementDO::getIsRecommended, param.getIsRecommended());
        wrapper.eq(Objects.nonNull(param.getIsDisplayed()), ProductManagementDO::getIsDisplayed, param.getIsDisplayed());
        wrapper.eq(Objects.nonNull(param.getStatus()), ProductManagementDO::getStatus, param.getStatus());
        Page<ProductManagementDO> page = productManagementMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
        Page<ProductManagementVO> pageInfo = ProductConvert.INSTANCE.doToVoPage(page);
        return new PageResult<>(pageInfo);
    }

    @Override
    public ProductManagementDetailVO getDetail(Long id) {
        return ProductConvert.INSTANCE.doToVo(productManagementMapper.selectById(id));
    }

    @Override
    public void create(ProductManagementParam param) {
        productManagementMapper.insert(ProductConvert.INSTANCE.managementParToDo(param));

    }

    @Override
    public void update(ProductManagementParam param) {
        productManagementMapper.updateById(ProductConvert.INSTANCE.managementParToDo(param));

    }

    @Override
    public void updateSelective(ProductManagementUpdateParam param) {
        productManagementMapper.updateById(ProductConvert.INSTANCE.managementUpdateSelectiveParToDo(param));

    }

    @Override
    public void delete(Long id) {
        productManagementMapper.deleteById(id);
    }

    @Override
    public PageResult<ProductVO> appList(ProductParam param) {
        LambdaQueryWrapper<ProductStatusDO> statusWrapper = new LambdaQueryWrapper<>();
        statusWrapper.eq(Objects.nonNull(param.getRecommendStatus()), ProductStatusDO::getRecommendStatus, param.getRecommendStatus());
        statusWrapper.eq(ProductStatusDO::getStatus, 0);
        statusWrapper.select(ProductStatusDO::getProductId);
        List<ProductStatusDO> productIdList = productStatusMapper.selectList(statusWrapper);

        List<Long> idList = productIdList.stream().map(ProductStatusDO::getProductId).collect(Collectors.toList());
        LambdaQueryWrapper<ProductDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ProductDO::getId, idList);
        wrapper.eq(Objects.nonNull(param.getCategoryId()), ProductDO::getCategoryId, param.getCategoryId());
        Page<ProductDO> page = productMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
        Page<ProductVO> pageInfo = ProductConvert.INSTANCE.do2VoPage(page);
        List<ProductVO> productVOList = pageInfo.getRecords();
        List<Long> pageIdList = productVOList.stream().map(ProductVO::getId).collect(Collectors.toList());
        LambdaQueryWrapper<ProductSkuDO> skdWrapper = new LambdaQueryWrapper<>();
        skdWrapper.in(CollectionUtils.isNotEmpty(pageIdList), ProductSkuDO::getProductId, pageIdList);
        List<ProductSkuDO> productSkuList = productSkuMapper.selectList(skdWrapper);
        Map<Long, ProductSkuDO> skuMap = productSkuList.stream().collect(Collectors.toMap(ProductSkuDO::getProductId, Function.identity(), (x, y) -> x));
        for (ProductVO productVO : productVOList) {
            ProductSkuDO sku = skuMap.get(productVO.getId());
            productVO.setOriginalPrice(sku.getMarketPrice());
            productVO.setMinPrice(sku.getSalePrice());
        }
        return new PageResult<>(pageInfo);
    }

    @Override
    public ProductDetailVO detail(Long id) {
        ProductDetailVO productDetail = new ProductDetailVO();
        ProductDO productDO = productMapper.selectById(id);
        List<JSONObject> picList = Lists.newArrayList();
        String pic = productDO.getPic();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("pic", pic);
        picList.add(jsonObject);
        String pics = productDO.getPics();
        if (StringUtils.isNotBlank(pics)) {
            for (String p : pics.split(",")) {
                jsonObject.put("pic", p);
                picList.add(jsonObject);
            }
        }
        productDetail.setPics(picList);

        ProductInfoVO productInfo = new ProductInfoVO();
        productInfo.setId(productDO.getId());
        productInfo.setCategoryId(productDO.getCategoryId());
        productInfo.setName(productDO.getName());
        LambdaQueryWrapper<ProductSkuDO> skdWrapper = new LambdaQueryWrapper<>();
        skdWrapper.eq(ProductSkuDO::getProductId, id);
        List<ProductSkuDO> productSkuList = productSkuMapper.selectList(skdWrapper);
        ProductSkuDO skuDO = productSkuList.get(0);
        productInfo.setOriginalPrice(skuDO.getMarketPrice());
        productInfo.setMinPrice(skuDO.getSalePrice());
        productInfo.setCharacteristic(productDO.getCharacteristic());
        productInfo.setStores(skuDO.getStockQuantity());
        productDetail.setBasicInfo(productInfo);

        List<ProductSpecVO> skuList = Lists.newArrayList();
        for (ProductSkuDO productSku : productSkuList) {
            ProductSpecVO dto = new ProductSpecVO();
            dto.setPropertyChildIds(productSku.getSpecJson());
            dto.setPropertyChildNames(productSku.getSpecText());
            dto.setOriginalPrice(productSku.getMarketPrice());
            dto.setPrice(productSku.getSalePrice());
            dto.setStores(productSku.getStockQuantity());
            skuList.add(dto);
        }
        productDetail.setSkuList(skuList);

        List<ProductSpecSkuDTO> productSpec = productSkuMapper.getProductSpec(id);
        if (CollectionUtils.isNotEmpty(productSpec)) {
            List<ProductSpecItemVO> properties = Lists.newArrayList();
            Map<Long, List<ProductSpecSkuDTO>> groupByOption = productSpec.stream().collect(Collectors.groupingBy(ProductSpecSkuDTO::getSpecOptionId));
            for (Map.Entry<Long, List<ProductSpecSkuDTO>> entry : groupByOption.entrySet()) {
                Long optionId = entry.getKey();
                List<ProductSpecSkuDTO> groupItems = entry.getValue();

                // 构建规格项（外层对象）
                ProductSpecItemVO property = new ProductSpecItemVO();
                // 规格项ID和名称（取分组中第一个元素的信息，确保同一组信息一致）
                ProductSpecSkuDTO first = groupItems.get(0);
                property.setId(optionId);
                property.setName(first.getSpecOptionName());

                // 构建规格值列表（childsCurGoods）
                List<ProductSpecItemVO> valueList = groupItems.stream().map(spec -> {
                    ProductSpecItemVO value = new ProductSpecItemVO();
                    value.setId(spec.getSpecValueId());
                    value.setName(spec.getSpecValueName());
                    return value;
                }).collect(Collectors.toList());

                property.setChildsCurGoods(valueList);
                properties.add(property);
            }
            productDetail.setProperties(properties);
        }
        productDetail.setContent(productDO.getContent());
        return productDetail;
    }

}
